package org.biogroovy.io.local;

import java.io.File;
import org.biogroovy.models.Gene;

/**
 * This class is responsible for writing a gene or list of genes in CSV format.
 * 
 * @author markfortner
 *
 */
public class Gene2CSVWriter {
	
	boolean includeHeader = true;
	boolean overwriteFile = true;
	String delimiter = "\t"
	String rowDelimiter = System.getProperty("line.separator");

	/**
	 * No args constructor
	 */
	public Gene2CSVWriter(){
		
	}
	
	/**
	 * Constructor
	 * @param includeHeader  indicates whether or not to include a header with the field names at the top of the file.
	 * @param overwriteFile  indicates whether or not to overwrite the output file if it already exists.
	 * @param delimiter		 The delimiter to be used to separate the values.
	 */
	public Gene2CSVWriter(boolean includeHeader, boolean overwriteFile, String delimiter){
		this.includeHeader = includeHeader;
		this.overwriteFile = overwriteFile;
		this.delimiter = delimiter;
	}
	
	/**
	 * This method outputs a list of genes to a file.
	 * @param geneList  A list of genes.
	 * @param filename  The output file.
	 * @see org.biogroovy.models.Gene
	 * @throws IOException if the file already exists, and the writer is set not to overwrite the file.
	 */
	public void output(List<Gene> geneList, String filename) throws IOException{
		File file = new File(filename);
		if (this.overwriteFile){
			output(geneList, new FileOutputStream(file));
		}else if (!this.overwriteFile && file.exists) {
			throw new IOException("Unable to overwrite file: ${filename}")
		}
	}
	
	/**
	 * This method outputs a single gene to a file.
	 * @param gene The gene to be exported.
	 * @param filename  The output file.
	 * @see org.biogrovy.models.Gene
	 * @throws IOException if the file already exists, and the writer is set not to overwrite the file.
	 */
	public void output(Gene gene, String filename) throws IOException{
		File file = new File(filename);
		if (this.overwriteFile){
			output(gene, new FileOutputStream(file));
		}else if (!this.overwriteFile && file.exists) {
			throw new IOException("Unable to overwrite file: ${filename}")
		}
	}
	
	
	/**
	 * This method outputs a list of Gene objects to an output stream. Note that this 
	 * method does not check whether or not the output stream points to a file that already exists.
	 * It will always overwrite the contents of a file.
	 * @param geneList  The list of genes to be output.
	 * @param os  The output stream
	 * @throws IOException if there is a problem writing the list to the file.
	 */
	public void output(List<Gene> geneList, OutputStream os) throws IOException{
		if (this.includeHeader){
			os << "Gene ID ${delimiter}"
			os << "Gene Symbol ${delimiter}"
			os << "Species ${delimiter}"
			os << "Synonyms ${delimiter}"
			os << "Gene Name ${delimiter}"
			os << "GO Function Terms ${delimiter}"
			os << "GO Process Terms ${delimiter}"
			os << "GO Component Terms ${delimiter}"
			os << "References "
			os << "${rowDelimiter}"
		}
		geneList.each(){
			output(gene, os);
		}
	}
	
	/**
	 * This method outputs a gene to the specified output stream.
	 * @param gene 	The gene to be output
	 * @param os  	The output stream
	 */
	public void output (Gene gene, OutputStream os) throws IOException{
		os << "${gene.entrezGeneId} ${delimiter}"
		os << "${gene.geneSymbol} ${delimiter}"
		os << "${gene.species} ${delimiter}"
		os << "${gene.synonyms} ${delimiter}"
		os << "${gene.geneName} ${delimiter}"
		gene.goFunctionList.eachWithIndex { it, i ->
		   if (i > 0){
			   os << ","
		   }
		os << "${it.name} ${delimiter}"
		}

		gene.goProcessList.eachWithIndex { it, i ->
		   if (i > 0){
			   os << ","
		   }
		os << "${it.name} ${delimiter}"
		}

		gene.goComponentList.eachWithIndex { it, i ->
		   if (i > 0){
			   os << ","
		   }
		os << "${it.name} ${delimiter}"
		}
		
		os << "${gene.references} "
		os << "${rowDelimiter}"
	}
	
	
	
}